import json

import requests
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from django.forms import model_to_dict
from web import models
from web.forms.file import FolderModelForm, FileModelForm
from utils.tencent.cos import delete_file, delete_file_list, credential


def file(request, project_id):
    """ 文件夹列表 & 添加文件夹 """
    parent_obj = None
    folder_id = request.GET.get('folder', '')

    if folder_id.isdecimal():
        parent_obj = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                          project=request.tracer.project).first()

    if request.method == "GET":
        # 定义文件导航  /././
        breadcrumb = []
        parent = parent_obj
        while parent:
            # breadcrumb.insert(0,{'id':parent_obj.id,'name':parent_obj.name})
            # 一直循环到根目录
            breadcrumb.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent
        form = FolderModelForm(request, parent_obj)
        queryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_obj:
            # 进入目录
            file_obj_list = queryset.filter(parent=parent_obj).order_by('-file_type')
        else:
            # 根目录
            file_obj_list = queryset.filter(parent__isnull=True).order_by('-file_type')

        # 将数据返回到前端页面
        content = {
            'form': form,
            'file_obj_list': file_obj_list,  # 文件对象
            'breadcrumb': breadcrumb,  # 目录列表
            'current_folder': parent_obj,
        }
        return render(request, 'file.html', content)

    # post 文件夹的添加 & 文件夹的修改
    fid = request.POST.get('fid')
    edit_obj = None
    if fid.isdecimal():
        edit_obj = models.FileRepository.objects.filter(id=int(fid), file_type=2,
                                                        project=request.tracer.project).first()
    if edit_obj:
        # 编辑
        form = FolderModelForm(request, parent_obj, data=request.POST, instance=edit_obj)
    else:
        # 添加
        form = FolderModelForm(request, parent_obj, data=request.POST)
    if form.is_valid():
        # 添加 modelform 中未定义的字段
        form.instance.project = request.tracer.project
        form.instance.file_type = 2
        form.instance.parent = parent_obj
        form.instance.update_user = request.tracer.user

        form.save()
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    # 获取要删除的文件/文件夹id
    fid = request.GET.get('fid')
    # print(fid)
    # print(request.GET)
    delete_obj = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_obj.file_type == 1:
        # 删除文件（数据库中删除文件，cos文件删除，项目容量释放）
        request.tracer.project.space_used -= delete_obj.file_size
        request.tracer.project.save()
        # 在 cos 中删除
        delete_file(bucket=request.tracer.project.bucket, region=request.tracer.project.region, key=delete_obj.key)
        # 在数据库中删除文件
        delete_obj.delete()
        return JsonResponse({'status': True})

    # 删除文件夹
    # 删除文件夹中包含的所有文件（数据库中删除文件，cos文件删除，项目容量释放）
    folder_list = [delete_obj, ]
    total_size = 0
    key_list = []
    for folder in folder_list:
        child_obj = models.FileRepository.objects.filter(project=request.tracer.project, parent=delete_obj)
        for child in child_obj:
            if child.file_type == 2:
                folder_list.append(child)
            else:
                total_size += child.file_size
                key_list.append({'key': child.key})
    if key_list:
        # cos 批量删除
        delete_file_list(bucket=request.tracer.project.bucket, region=request.tracer.project.region, key_list=key_list)
    if total_size:
        # 归还容量
        request.tracer.project.space_used -= total_size
        request.tracer.project.save()

    # 删除数据中的文件
    delete_obj.delete()
    return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    """获取cos上传临时凭证"""
    # 单文件最大限制
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    # 项目总容量最大限制
    total_file_limit = request.tracer.price_policy.project_space * 1024 * 1024 * 1024

    total_size = 0
    file_list = json.loads(request.body.decode('utf-8'))
    for file in file_list:
        if file['size'] > per_file_limit:
            msg = "超过单文件最大限制（最大{}M），文件{}，请升级套餐".format(request.tracer.price_policy.per_file_size, file['name'])
            return JsonResponse({'status': False, 'error': msg})
        total_size += file['size']

    if request.tracer.project.space_used + total_size > total_file_limit:
        return JsonResponse({'status': False, 'error': "超过最大容量限制，请升级套餐"})

    data_dict = credential(bucket=request.tracer.project.bucket, region=request.tracer.project.region)
    return JsonResponse({'status': True, 'data': data_dict})


@csrf_exempt
def file_post(request, project_id):
    """ 已上传成功的文件写入数据库 """
    """
    name: fileName,
    key: key,
    file_size: fileSize,
    parent: PARENT_ID,
    etag:data.ETag,
    file_path:data.Location,
    """
    form = FileModelForm(request,data=request.POST)
    if form.is_valid():
        # 校验通过,写入数据库
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        instance = models.FileRepository.objects.create(**data_dict)

        # 项目已使用空间 更新 data_dict['file_size']
        request.tracer.project.space_used += data_dict['file_size']
        request.tracer.project.save()
        # 返回到前端的数据
        result = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datetime': instance.update_time.strftime("%Y{}%m{}%d{}%H:%M").format("年","月","日"),
            'download_url': reverse('file_download',kwargs={'project_id':project_id,'file_id':instance.id})
            # 'file_type':instance.get_file_type_display(),
        }
        return JsonResponse({'status': True, 'data': result})

    return JsonResponse({})


def file_download(request,project_id,file_id):
    file_obj = models.FileRepository.objects.filter(id=file_id,project_id=project_id,).first()
    print(file_obj)
    file_path = file_obj.file_path

    res = requests.get(file_path)
    # data = res.content
    # 文件分块处理（适用于大文件）
    data = res.iter_content()

    # 设置content_type='application/octet-stream' 用于提示下载
    response = HttpResponse(data,content_type='application/octet-stream')
    from django.utils.encoding import escape_uri_path

    # 设置响应头;中文文件名转义
    response['Content-Disposition'] =  'attachment;filename={}'.format(escape_uri_path(file_obj.name))
    return response